App.require(function () {
    App.defineWidgetBehavior("pos", {
        render: function (ctx) {
            var widget = this.target, option = this.option;
            ctx.save();
            ctx.translate(widget.x, widget.y);
            ctx.fillStyle = option.fill;
            ctx.strokeStyle = option.stroke;
            ctx.beginPath();
            ctx.arc(0, 0, option.radius, 0, Math.PI * 2, false);
            ctx.fill();
            ctx.stroke();
            ctx.restore();
        },
        getEventRange: function (pos) {
            var widget = this.target, x = pos.x - widget.x, y = pos.y - widget.y, option = this.option;
            return x * x + y * y < option.radius * option.radius;
            // var pos = this.target._inverse(pos), option = this.option;
            // return pos.x * pos.x + pos.y * pos.y < option.radius * option.radius;
        },
        option: {
            fill: "orange",
            stroke: "black",
            radius: 10
        },
        initialize: function () {
            this.data.startX = 0;
            this.data.startY = 0;
            this.data.initX = 0;
            this.data.inity = 0;
            this.data.deltaX = 0;
            this.data.deltaY = 0;
            this.data.isDown = false;
            this.attachDiyEvent("mousedown", this.mousedownHandler)
                .attachDiyEvent("mousemove", this.mousemoveHandler)
                .attachDiyEvent("mouseup", this.mouseupHandler);
        },
        mousedownHandler: function (ev) {
            if (this.getEventRange(ev)) {
                this.data.isDown = true;
                this.data.startX = ev.x;
                this.data.startY = ev.y;
                this.data.initX = this.target.style.x;
                this.data.initY = this.target.style.y;
            }
        },
        mousemoveHandler: function (ev) {
            if (this.data.isDown) {
                this.data.deltaX = ev.x - this.data.startX;
                this.data.deltaY = ev.y - this.data.startY;
                this.target.updatePropertyExcept("x", this.data.initX + this.data.deltaX, null);
                this.target.updatePropertyExcept("y", this.data.initY + this.data.deltaY, null)
            }
        },
        mouseupHandler: function (ev) {
            this.data.isDown = false;
            this.data.startX = 0;
            this.data.startY = 0;
            this.data.deltaX = 0;
            this.data.deltaY = 0;
        },
        toForm: {
            x: {
                element: function () {
                    return {
                        type: "range",
                        min: 0,
                        max: 800,
                        step: 1
                    }
                },
                initValue: function () {
                    return this.x;
                },
                callback: function (key, value, element) {
                    this.updatePropertyExcept(key, parseInt(value), element);
                }
            },
            y: {
                element: function () {
                    return {
                        type: "range",
                        min: 0,
                        max: 800,
                        step: 1
                    }
                },
                initValue: function () {
                    return this.y;
                },
                callback: function (key, value, element) {
                    this.updatePropertyExcept(key, parseInt(value), element);
                }
            }
        },
    });
})